package com.pray.security.handler;

import com.pray.entity.po.Account;
import com.pray.entity.vo.response.AuthorizeVO;
import com.pray.service.AccountService;
import com.pray.utils.JwtUtils;
import com.pray.utils.PrayConstants;
import com.pray.utils.Result;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * LoginSuccessHandler
 * <p>
 *
 * @author 春江花朝秋月夜
 * @since 2023/9/6 13:30
 */
@Slf4j
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    AccountService accountService;
    JwtUtils jwtUtils;
    StringRedisTemplate stringRedisTemplate;
    public LoginSuccessHandler(AccountService accountService, JwtUtils jwtUtils,StringRedisTemplate stringRedisTemplate) {
        this.accountService = accountService;
        this.jwtUtils = jwtUtils;
        this.stringRedisTemplate=stringRedisTemplate;
    }
    // TODO 无法实现下面两个类的注入，这里我采用构造方法的办法来获取这两个参数
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        //获取Spring Security封装的User对象
        User user = (User) authentication.getPrincipal();
        Account account = accountService.findUserByNameOrEmail(user.getUsername());
        String jwt=jwtUtils.createJwt(user, account.getUsername());
        //创建权限视图层对象
        AuthorizeVO vo = new AuthorizeVO();
        vo.setToken(jwt);
        vo.setUsername(account.getUsername());
        //颁发token同时需要将获取到的用户信息存储到Redis里面
        //TODO 下面这一段可以写成Lamda表达式
        HashMap<String, String> userMap = new HashMap<>();
        //TODO 下面需要更改逻辑
        userMap.put("username", vo.getUsername());
        userMap.put("token", vo.getToken());

        String key = PrayConstants.LOGIN_USER_KEY + vo.getToken();
        stringRedisTemplate.opsForHash().putAll(key,userMap);
        stringRedisTemplate.expire(PrayConstants.LOGIN_USER_KEY,PrayConstants.LOGIN_USER_TTL, TimeUnit.SECONDS);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(Result.ok(vo).JsonResult());
    }

}
